不管是JavaScript還是其他程式語言,通常都是逐行執行的,
在之前的例子中,都會先宣告好變數跟函式再使用。
像這樣
function say() {
console.log('hello world');
}
var num = 2;
console.log(num);//2
say(); //印出hello world
畢竟沒有宣告的話,執行時會跳出錯誤,以正常人的邏輯都是建立好一個值後才能使用。
那如果反過來,先使用才宣告呢?
console.log(num);//undefined
say();//印出hello world
function say() {
console.log('hello world');
}
var num = 2;
此時不會跳錯誤,函式能正常執行,但變數印出的結果變成undefined,代表函式跟變數有被宣告,但變數沒有被賦值。
有人會說其實是JavaScript幫你把程式碼處理過了,
處理過的程式碼長這樣:
function say() {
console.log('hello world');
}
var num;
console.log(num);//因為還沒有賦值 所以印出undefined
say();//印出hello world
num = 2;
JavaScript幫你把宣告拉到程式的最上面,所以這種情況叫做提升
(Hoisting)
執行結果一樣,但不代表真的是這樣運作,
如果JavaScript真的亂移動程式碼大概會被罵死(
實際上會造成這種情況的原因,是JavaScript在建立新執行環境時的處理,建立新執行環境時,JavaScript先確定好環境內可以使用的變數跟函式,為其配置記憶體空間
一樣用這個程式當作範例
console.log(num);
say();
function say() {
console.log('hello world');
}
var num = 2;
JavaScript對這程式的處理程序是:
say()
,在記憶體配置num
,在記憶體配置變數num
,但還沒有值num
的值(undefined)say()
,建立區域環境,不過環境內沒有變數跟函式hello world
,執行結束區域環境消滅num
所以拉升可以讓我們把函式宣告在喜歡的位置,讓程式碼更好理解
像如果想實作一個把陣列依照英文字母排序的函式
function sortArrayByName(arr) {
return arr.sort(function (a, b) {
for (let i = 0; i < Math.min(a.length, b.length); i++) {
if (a[i] > b[i]) {
return 1;
} else if (a[i] < b[i]) {
return -1;
}
}
return a.length > b.length ? 1 : -1;
});
}
直接在引數的位置寫排序用的函式會很難閱讀,
把排序用函式宣告在上方的話會好讀一點,但還是讀到最後一行才知道這個函式在做甚麼。
但如果利用提升
function sortArrayByName(arr) {
return arr.sort(sortByName);
//------------------------------
function sortByName(a, b) {
for (let i = 0; i < Math.min(a.length, b.length); i++) {
if (a[i] > b[i]) {
return 1;
} else if (a[i] < b[i]) {
return -1;
}
}
return a.length > b.length ? 1 : -1;
}
}
用這方式只要看第一行就知道sortArrayByName
這函式會回傳甚麼,
想看排序的方式詳細才需要看下半部。